home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / tmeshobj.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  5KB  |  253 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    tmeshobj-
  19.  *        Convert an sgi obj into triangle meshes.
  20.  *
  21.  *            Paul Haeberli - 1990
  22.  */
  23. #include "sgiobj.h"
  24. #include "mesh.h"
  25.  
  26. static sgiobj *outobj;
  27. static long *outptr;
  28. static int np;
  29. static int vcount;
  30. static int lastcmd;
  31. static long *countpos;
  32.  
  33. /*
  34.  *    hashlongs -
  35.  *        this returns an integer hash value for an array of longs.
  36.  *
  37.  */
  38. static long hashlongs(buf,n)
  39. long *buf;
  40. {
  41.     long hash;
  42.  
  43.     hash = 0;
  44.     while(n--)
  45.     hash = (273*hash)+(*buf++);
  46.     return hash&0x7fffffff;
  47. }
  48.  
  49. /*
  50.  *     newcommand - 
  51.  *
  52.  *        is used to create a triangle meshed sgo format object 
  53.  *        in memory.
  54.  */
  55. static newcommand(op)
  56. long op;
  57. {
  58.     if(op == OP_BGNTMESH && lastcmd == OP_ENDTMESH && vcount == 0) {
  59.     outptr[-2] = OP_ENDBGNTMESH;
  60.     return;
  61.     }
  62.     if(vcount>0) {
  63.     *countpos = vcount;
  64.     vcount = 0;
  65.     }
  66.     lastcmd = op;
  67.     *outptr++ = op;
  68.     countpos = outptr;
  69.     outptr++;
  70. }
  71.  
  72.  
  73. /* initialization functions follow */
  74.  
  75. /*
  76.  *    out_ambegin - 
  77.  *
  78.  *        the mesh package calls this rountine with the total number of 
  79.  *        verticies and triangles in the tmeshed object.
  80.  */
  81. static void out_ambegin(nverts,ntris)
  82. int nverts, ntris;
  83. {
  84.     int maxlongs;
  85.  
  86.     maxlongs = 2+(nverts*PNTLONGS)+(3*np*5)+1;
  87.     outobj = (sgiobj *)newtmeshobj(maxlongs);
  88.     outptr = outobj->data;
  89.     *outptr++ = PNTLONGS*nverts;
  90.     vcount = 0;
  91.     lastcmd = 0;
  92. }
  93.  
  94. /*
  95.  *    out_amend - 
  96.  *
  97.  *        the mesh package calls this rountine as the very last thing
  98.  *        it does.
  99.  */
  100. static void out_amend()
  101. {
  102.     outobj->nlongs = outptr-outobj->data;
  103. }
  104.  
  105. /* comparison functions follow */
  106.  
  107. /*
  108.  *    out_amhashvert - 
  109.  *
  110.  *        this function will take all the interesting data for a 
  111.  *        vertex and return an integer hash value.  this is used to
  112.  *        make vertex comparison operations much more efficient
  113.  *        for large objects.
  114.  */
  115. static int out_amhashvert(long v)
  116. {
  117.     return hashlongs(v,9);
  118. }
  119.  
  120. /*
  121.  *    out_amvertsame - 
  122.  *
  123.  *        this function will take all the interesting data for a 
  124.  *        vertex and return an value of 1 if the verticies are identical
  125.  *        and 0 if they differ.
  126.  */
  127. static int out_amvertsame(long l1, long l2)
  128. {
  129.     float *v1, *v2;
  130.  
  131.     v1 = (float *)l1;
  132.     v2 = (float *)l2;
  133.     if(v1[0] != v2[0]) return 0;
  134.     if(v1[1] != v2[1]) return 0;
  135.     if(v1[2] != v2[2]) return 0;
  136.  
  137.     if(v1[3] != v2[3]) return 0;
  138.     if(v1[4] != v2[4]) return 0;
  139.     if(v1[5] != v2[5]) return 0;
  140.  
  141.     if(v1[6] != v2[6]) return 0;
  142.     if(v1[7] != v2[7]) return 0;
  143.     if(v1[8] != v2[8]) return 0;
  144.  
  145.     return 1;
  146. }
  147.  
  148. /* output functions follow */
  149.  
  150. /*
  151.  *    out_amvertdata - 
  152.  *
  153.  *        this function will be called once for each vertex in the 
  154.  *        tmeshed object.  The order of these verticies are used
  155.  *        by out_amvert below.        
  156.  */
  157. static void out_amvertdata(long fptr)
  158. {
  159.     bcopy(fptr,outptr,9*sizeof(long));
  160.     outptr += PNTLONGS;
  161. }
  162.  
  163. /*
  164.  *    out_ambgntmesh - 
  165.  *
  166.  *        this function indicates the start of a GL tmesh.
  167.  */
  168. static void out_ambgntmesh(void) 
  169. {
  170.     newcommand(OP_BGNTMESH);
  171. }
  172.  
  173. /*
  174.  *    out_amendtmesh - 
  175.  *
  176.  *        this function indicates the end of a GL tmesh.
  177.  */
  178. static void out_amendtmesh(void) 
  179. {
  180.     newcommand(OP_ENDTMESH);
  181. }
  182.  
  183. /*
  184.  *    out_amswaptmesh - 
  185.  *
  186.  *        this function indicates a swap tmesh.
  187.  */
  188. static void out_amswaptmesh(void) 
  189. {
  190.     newcommand(OP_SWAPTMESH);
  191. }
  192.  
  193. /*
  194.  *    out_amvert - 
  195.  *
  196.  *        this function indicates the index of a vertex to output
  197.  *        inside a tmesh.
  198.  */
  199. static void out_amvert(long index)
  200. {
  201.     *outptr++ = PNTLONGS*index*sizeof(long);
  202.     vcount++;
  203. }
  204.  
  205. /*
  206.  *    tmeshobj -
  207.  *        this takes an sgiobj that is stored as a list of trianlges
  208.  *    and returns a triangle mesh format object.
  209.  */
  210. sgiobj *tmeshobj(obj)
  211. sgiobj *obj;
  212. {
  213.     int poly, i;
  214.     float *fptr;
  215.     Meshobj *mc;
  216.  
  217. /* initialize the meshing package */
  218.     mc = newMeshobj( out_ambegin,
  219.             out_amend,
  220.             out_amhashvert,
  221.             out_amvertsame,
  222.             out_amvertdata,
  223.             out_ambgntmesh,
  224.             out_amendtmesh,
  225.             out_amswaptmesh,
  226.             out_amvert);
  227.  
  228. /* indicate start of triangles */
  229.     in_ambegin(mc);
  230.  
  231.     np = (obj->nlongs/PNTLONGS)/3;
  232.     fptr = (float*)obj->data;
  233.     for(poly=0; poly<np; poly++) {
  234.  
  235. /* start a  triangle */
  236.     in_amnewtri(mc);
  237.  
  238. /* push out the vertex addresses */
  239.     for(i=0; i<3; i++) {
  240.         in_amvert(mc,(long)fptr);
  241.         fptr += PNTLONGS;
  242.     }
  243.     }
  244.  
  245. /* indicate end of the triangles */
  246.     in_amend(mc);
  247.  
  248. /* free storage allocated for meshing */
  249.     freeMeshobj(mc);
  250.  
  251.     return outobj;
  252. }
  253.